// Copyright DustedPixels.com 2008. All rights reserved.

package com.dustedpixels.asm.analysis;

import java.util.HashSet;
import java.util.Set;

import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.analysis.Value;

import com.dustedpixels.common.Objects;

/**
 * @author micapolos@gmail.com (Michal Pociecha-Los)
 */
public final class TargetValue implements Value {
  private final int size;
  private final Set<AbstractInsnNode> targets;
  private final TargetValue value1;
  private final TargetValue value2;
  
  static TargetValue like(Value value) {
    return (value == null) 
        ? null
        : new TargetValue(value.getSize(), null, null);
  }
  
  static TargetValue merged(TargetValue value1, TargetValue value2) {
    return new TargetValue(value1.size, value1, value2);
  }
  
  TargetValue(int size, TargetValue value1, TargetValue value2) {
    this.size = size;
    this.value1 = value1;
    this.value2 = value2;
    this.targets = new HashSet<AbstractInsnNode>();
  }
  
  public int getSize() {
    return size;
  }
  
  public Set<AbstractInsnNode> getTargets() {
    return targets;
  }
  
  void addTarget(AbstractInsnNode insn) {
    targets.add(insn);
    if (value1 != null) value1.addTarget(insn);
    if (value2 != null) value2.addTarget(insn);
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (!(obj instanceof TargetValue)) return false;
    TargetValue otherValue = (TargetValue) obj;
    return (size == otherValue.size) &&
           Objects.eq(value1, otherValue.value1) &&
           Objects.eq(value2, otherValue.value2);
  }

  @Override
  public String toString() {
    return "TargetValue(" + size + "," + value1 + "," + value2 + ")";
  }
}